15min_adventure - cr3 2024
#cr3_2024 #crackme #Windows
入力された文字列に対して何回かxorをした後、バイナリ内の定数と比較している
デコンパイル結果から正しい入力を復元するとcr3{c0ngr4t5_0n_f1nd1ng_th3_fake_flag}が得られる
フラグから分かる通り、これはfake flag
バイナリの挙動をデバッガで追うと、RtlCaptureContextで関数を呼び出していることがわかる(sub_1400017E0)
この関数でもxorおよびrorをしていることがわかるので、これを考慮して正しい入力を復元すると正しいフラグが得られる
code: solve.py
a = -19977, 474495962, 0x7162456D69F3005, 0x36161B6C3DFBB437, 0xF3BFF9C2BC24994F, 0xC5EFD8928EEF23AC,
arr1 = b''.join([int.to_bytes(it & 0xffffffffffffffff, 8, 'little') for it in a::-1])
arr1 = arr1:36 + arr140:42
b = -21770, 457325539, 0x41B2356EFCA3E17, 0xF17133B3FF3E337, 0xCAB7AFFBEF36CB5B, 0xC4E78E9793BA37A9,
arr2 = b''.join([int.to_bytes(it & 0xffffffffffffffff, 8, 'little') for it in b::-1])
arr2 = arr2:36 + arr240:42
c = -11448, -1836494567, 0xC7EAB4322C5C7F7E, 0x33EAF1E46E35ECF2, 0x4F47D6FC1CE792C, 0x3E08C15356000F44,
arr3 = b''.join([int.to_bytes(it & 0xffffffffffffffff, 8, 'little') for it in c::-1])
arr3 = arr3:36 + arr340:42
ror = lambda val, r_bits, max_bits: \
((val & (2**max_bits-1)) >> r_bits%max_bits) | \
(val << (max_bits-(r_bits%max_bits)) & (2**max_bits-1))
flag1 = [arr1i ^ arr2i for i in range(len(arr1))]
print(flag1)
flag2 = [ror(flag1i, 2, 8) ^ (arr3i + i) ^ i for i in range(len(flag1))]
print(flag2)
flag3 = [chr((flag2i ^ 0x66) & 0xff) for i in range(len(flag2))]
print(''.join(flag3))